import router from './router'
import store from './store'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { user } from 'api'
import { asyncRoutes, constantRoutes } from '@/router'
import { getStore } from './utils/util'

function hasPermissionOption(subRoute, powers) {
  if (powers.indexOf(subRoute.meta.code) > -1) {
    return true
  }

  return false
}

function hasPermission(asyncRoutes, roles) {
  // 新建路由列表数组
  let res = []
  //循环遍历 全部路由列表 遍历左边导航一级
  for (let modular of asyncRoutes) {
    // 新建二级路由列表数组
    let routes = []
    // 遍历左边导航一级下的二级导航路由
    for (let route of modular.children) {
      // 检测二级路由中的路由码 是否 在路由码数组里，有就把路由放到新的路由列表数组里
      let routeRes = hasPermissionOption(route, roles)
      routeRes && routes.push(route)
    }

    if (routes.length) {
      let obj = {}
      modular.redirect = routes[0].path //修改一级菜单的重定向路径
      obj = modular
      obj.children = routes
      res.push(obj)
    }
  }
  return res
}

function filterAsyncRoutes(asyncRoutes, roles) {
  let res = hasPermission(asyncRoutes, roles)
  res.sort((a, b) => {
    return a.meta.sort - b.meta.sort
  })
  // 返回一个正确路由数组
  return res
}

function generateRoutes(roles) {
  let accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)

  store.commit('setRoutes', accessedRoutes)
  return accessedRoutes
}

const whiteList = ['/login', '/dingding'] //白名单

router.beforeEach(async (to, from, next) => {
  NProgress.start()
  document.title = to.meta.title
  const hasToken = getStore('token')

  if (hasToken) {
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      let { roles } = store.getters
      const hasRoles = roles && roles.length > 0
      if (hasRoles) {
        next()
      } else {
        try {
          //拿到全部的路由码(根据每个用户不同返回不同的路由码数组)
          const { roles } = user.getUserInfo()

          // 这里accessRoutes 是一个通过后端给的路由码过滤后的该用户有权限的路由数组
          const accessRoutes = generateRoutes(roles)
          accessRoutes.forEach((item) => {
            router.addRoute(item)
          })

          let newRedirect = accessRoutes[0].children[0].path
          if (newRedirect !== '/oneModular/' && to.path === '/oneModular') {
            constantRoutes[0].redirect = newRedirect
            next({ path: newRedirect })
          } else {
            next({ ...to, replace: true })
          }
        } catch (error) {
          store.commit('setInfo', {})

          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})
